function isObject (target) {
  return (typeof target === 'function' || typeof target === 'object') && target !== null
}
function deepClone (target, map = new WeakMap()) {
  if (map.get(target)) {
    return target
  }
  let constructor = target.constructor
  if (/^(RegExp|Date)$/i.test(constructor.name)) {
    return new constructor(target)
  }
  if (isObject(target)) {
    map.set(target, true)
    if (typeof target === 'function') {
      return target
    }
    let cloneTarget = Array.isArray(target) ? [] : {}
    for (let key in target) {
      if (target.hasOwnProperty(key)) {
        cloneTarget[key] = deepClone(target[key], map)
      }
    }
    return cloneTarget
  } else {
    return target
  }
}
let c = {
  name: '方现伟',
  hobby: ['吃饭', '睡觉', '打豆豆'],
  power: {
    '馒头': 20,
    '包子': 30
  },
  say: function () {
    console.log('我喜欢吃' + this.hobby[0]);
  },
  birth: new Date(),
  shabi: /^傻逼$/
}
let d = deepClone(c)
d.name = '王晶晶'
d.hobby.push('拉屎')
d.power['馒头'] = 30
console.log(c);
console.log(d);
// d.say()